package com.strangebreeds.therefromhere.engine;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;

public class Configuration
{
	// The inner class needs to be static if referred to by static methods
	static class ConfigXMLFile
	{
		// This is the name of the XML file that we read the settings from
		static private final String xmlFile = "config.xml";

		public InputStream theStream;

		ConfigXMLFile()
		{
			try
			{
				theStream = getClass().getEnclosingClass().getClassLoader().getResourceAsStream(xmlFile);
			}
			catch (Exception e)
			{
				System.out.println("Hmm...error was " + e.getMessage());
			}
		}
	}

	static private final Configuration.ConfigXMLFile configXMLFile = new Configuration.ConfigXMLFile();

	static private Logger logger = Logger.getLogger(Configuration.class);

	// This is the XML tree that holds everything in the file above
	static private Document settings;

	static
	{
		try
		{
			ReadConfiguration();
		}
		catch (IOException e)
		{
			logger.error("Caught IOException: " + e.getMessage(), e);
		}
		catch (ParserConfigurationException e)
		{
			logger.error("Caught ParserConfigurationException: " + e.getMessage(), e);
		}
		catch (org.xml.sax.SAXException e)
		{
			logger.error("Caught org.xml.sax.SAXException: " + e.getMessage(), e);
		}
	}

	private static void ReadConfiguration() throws IOException,
										   ParserConfigurationException,
										   org.xml.sax.SAXException
	{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setIgnoringComments(true); // Ignore comments
		factory.setCoalescing(true); // Convert CDATA to Text nodes
		factory.setNamespaceAware(false); // No namespace (yet)
		factory.setValidating(false); // Don't validate the DTD (yet)
		DocumentBuilder parser = factory.newDocumentBuilder();
		// Parse the file and build a document tree to represent its content
		settings = parser.parse(configXMLFile.theStream);
	}

	static public String getDatabaseUser()
	{
		String dbUser = new String();
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			dbUser = xpath.evaluate("/tfh/database/username", settings).trim();
			logger.debug("dbUser is " + dbUser);
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return dbUser;
	}

	static public String getDatabasePassword()
	{
		String dbPassword = new String();
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			dbPassword = xpath.evaluate("/tfh/database/password", settings).trim();
			logger.debug("dbPassword is " + dbPassword);
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}
		return dbPassword;
	}

	static public String getDatabaseConnectionString()
	{
		String dbServerConnString = new String();
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			dbServerConnString = xpath.evaluate("/tfh/database/connectstring", settings).trim();
			logger.debug("dbServerConnString is " + dbServerConnString);
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return dbServerConnString;
	}
	
	static public String getBaseWorkDirectory()
	{
		String dbServerConnString = new String();
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			dbServerConnString = xpath.evaluate("/tfh/work/base_directory", settings).trim();
			logger.debug("base directory is " + dbServerConnString);
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return dbServerConnString;
	}
	
	static public String getSMTPServer()
	{
		String emailServerConnString = new String();
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			emailServerConnString = xpath.evaluate("/tfh/email/server_name", settings).trim();
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return emailServerConnString;
	}
	
	static public String getSMTPPort()
	{
		String emailPort = new String();
		
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			emailPort = xpath.evaluate("/tfh/email/server_port", settings).trim();
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return emailPort;
	}
	
	static public String getFromAddress()
	{
		String fromAddress = new String();
		
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			fromAddress = xpath.evaluate("/tfh/email/from_address", settings).trim();
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return fromAddress;
	}
	
	static public String getSMTPUsername()
	{
		String username = new String();
		
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			username = xpath.evaluate("/tfh/email/username", settings).trim();
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return username;
	}
	
	static public String getSMTPPassword()
	{
		String password = new String();
		
		try
		{
			XPath xpath = XPathFactory.newInstance().newXPath();
			password = xpath.evaluate("/tfh/email/password", settings).trim();
		}
		catch (XPathExpressionException e)
		{
			logger.error("XPathExpressionException: " + e.getMessage(), e);
		}

		return password;
	}
}
